
package scalaSci.EJML

import scalaSci.Matrix
import scalaSci.RichDoubleDoubleArray
import scalaSci.RichNumber
import scalaSci.RichDoubleArray
import scalaSci.Vec
import org.ejml.data.Complex64F
import org.ejml.data.DenseMatrix64F


import scalaSci.math.LinearAlgebra.LinearAlgebra

// allows static methods of ScalaSci's mathematical objects (e.g. Matrix) to be conveniently available,
// e.g. sin(m) instead of scalaSci.Matrix.sin(m)

object StaticMathsEJML  {
     implicit def DoubleToRichNumber(x: Double) = {  new RichNumber(x)}  // implicit conversion of a Double number to RichNumber
     implicit def IntToRichNumber(x: Int) =  { new RichNumber(x)  }  // implicit conversion of a Int number to RichNumber
     implicit def ShortToRichNumber(x: Short) = { new RichNumber(x) }   // implicit conversion of a Short number to RichNumber
     implicit def LongToRichNumber(x: Long) = { new RichNumber(x)  }   // implicit conversion of a Long number to RichNumber

implicit def DoubleArrayToRichDoubleArray(x: Array[Double]) = {  new RichDoubleArray(x)}  // implicit conversion of an Array[Double] to RichDoubleNumber
implicit def DoubleDoubleArrayToRichDoubleArray(x: Array[Array[Double]]) =  {  new RichDoubleDoubleArray(x)}  // implicit conversion of an Array[Array[Double]] to RichDoubleDoubleArray
         

// when D[][] + Mat  (Matrix) convert D[][] to Mat (Matrix) without copying the array 
//     implicit def doubleDoubleArrToMatrix(x: Array[Array[Double]]) = { new scalaSci.Matrix(x, true)  }

   
        // EJMLMat <--> Matrix 
     implicit def EJMLMatToMatrix(x: scalaSci.EJML.Mat) = { scalaSci.EJML.Mat.toMatrix(x) }  
     implicit def MatrixToEJMLMat(x: scalaSci.Matrix) = { scalaSci.EJML.Mat.toEJMLMat(x) }  
    
 
// used for plotting routines
     implicit def VecToDoubleArr(x: Vec) = { x.getv }
     implicit def MatrixToDoubleArr(x: Matrix) = { x.getRow(1) }
     implicit def MatToDoubleArr(x: Mat) = { x(0) }


def V(s: String) =  scalaSci.Vec.V(s)

def M(str: String) =  scalaSci.EJML.Mat.M(str)

def M1(s: String) =   scalaSci.Matrix.M1(s)

def MDD(s: String) =   scalaSci.DoubleDoubleArr.MDD(s) 
     
def sin(x: Double) = {
    java.lang.Math.sin(x)
}

def sin(x: Float) = {
    java.lang.Math.sin(x).asInstanceOf[Float]
}

def sin(x: Int) = {
    java.lang.Math.sin(x)
}

def sin(x: Short) = {
    java.lang.Math.sin(x)
}

def sin(x: Long) = {
    java.lang.Math.sin(x)
}

def sin(x: Array[Double]) = {
    scalaSci.DoubleArr.sin(x)
}

def sin(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.sin(x)
}

def sin(x: Matrix) = {
    scalaSci.Matrix.sin(x)
}


def sin(x: Vec) = {
    scalaSci.Vec.sin(x)
}

// cos

def cos(x: Double) = {
    java.lang.Math.cos(x)
}


def cos(x: Float) = {
    java.lang.Math.cos(x).asInstanceOf[Float]
}

def cos(x: Int) = {
    java.lang.Math.cos(x)
}

def cos(x: Short) = {
    java.lang.Math.cos(x)
}

def cos(x: Long) = {
    java.lang.Math.cos(x)
}

def cos(x: Array[Double]) = {
    scalaSci.DoubleArr.cos(x)
}


def cos(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.cos(x)
}

def cos(x: Matrix) = {
    scalaSci.Matrix.cos(x)
}


def cos(x: Vec) = {
    scalaSci.Vec.cos(x)
}


//tan


def tan(x: Double) = {
    java.lang.Math.tan(x)
}


def tan(x: Float) = {
    java.lang.Math.tan(x).asInstanceOf[Float]
}

def tan(x: Int) = {
    java.lang.Math.tan(x)
}

def tan(x: Short) = {
    java.lang.Math.tan(x)
}

def tan(x: Long) = {
    java.lang.Math.tan(x)
}

def tan(x: Array[Double]) = {
    scalaSci.DoubleArr.tan(x)
}


def tan(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.tan(x)
}

def tan(x: Matrix) = {
    scalaSci.Matrix.tan(x)
}

def tan(x: Vec) = {
    scalaSci.Vec.tan(x)
}

// cosh
def cosh(x: Double) = {
    java.lang.Math.cosh(x)
}

def cosh(x: Float) = {
    java.lang.Math.cosh(x).asInstanceOf[Float]
}

def cosh(x: Int) = {
    java.lang.Math.cosh(x)
}

def cosh(x: Short) = {
    java.lang.Math.cosh(x)
}

def cosh(x: Long) = {
    java.lang.Math.cosh(x)
}

def cosh(x: Array[Double]) = {
    scalaSci.DoubleArr.cosh(x)
}


def cosh(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.cosh(x)
}

def cosh(x: Matrix) = {
    scalaSci.Matrix.cosh(x)
}



def cosh(x: Vec) = {
    scalaSci.Vec.cosh(x)
}


// sinh
def sinh(x: Double) = {
    java.lang.Math.sinh(x)
}

def sinh(x: Float) = {
    java.lang.Math.sinh(x).asInstanceOf[Float]
}

def sinh(x: Int) = {
    java.lang.Math.sinh(x)
}

def sinh(x: Short) = {
    java.lang.Math.sinh(x)
}

def sinh(x: Long) = {
    java.lang.Math.sinh(x)
}

def sinh(x: Array[Double]) = {
    scalaSci.DoubleArr.sinh(x)
}

def sinh(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.sinh(x)
}

def sinh(x: Matrix) = {
    scalaSci.Matrix.sinh(x)
}



def sinh(x: Vec) = {
    scalaSci.Vec.sinh(x)
}


// tanh
def tanh(x: Double) = {
    java.lang.Math.tanh(x)
}

def tanh(x: Float) = {
    java.lang.Math.tanh(x).asInstanceOf[Float]
}

def tanh(x: Int) = {
    java.lang.Math.tanh(x)
}

def tanh(x: Short) = {
    java.lang.Math.tanh(x)
}

def tanh(x: Long) = {
    java.lang.Math.tanh(x)
}

def tanh(x: Array[Double]) = {
    scalaSci.DoubleArr.tanh(x)
}


def tanh(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.tanh(x)
}

def tanh(x: Matrix) = {
    scalaSci.Matrix.tanh(x)
}

def tanh(x: Vec) = {
    scalaSci.Vec.tanh(x)
}


// asin

def asin(x: Double) = {
    java.lang.Math.asin(x)
}

def asin(x: Float) = {
    java.lang.Math.asin(x).asInstanceOf[Float]
}

def asin(x: Int) = {
    java.lang.Math.asin(x)
}

def asin(x: Short) = {
    java.lang.Math.asin(x)
}

def asin(x: Long) = {
    java.lang.Math.asin(x)
}

def asin(x: Array[Double]) = {
    scalaSci.DoubleArr.asin(x)
}

def asin(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.asin(x)
}

def asin(x: Matrix) = {
    scalaSci.Matrix.asin(x)
}


def asin(x: Vec) = {
    scalaSci.Vec.asin(x)
}


    // acos

def acos(x: Double) = {
    java.lang.Math.acos(x)
}

def acos(x: Float) = {
    java.lang.Math.acos(x).asInstanceOf[Float]
}

def acos(x: Int) = {
    java.lang.Math.acos(x)
}

def acos(x: Short) = {
    java.lang.Math.acos(x)
}

def acos(x: Long) = {
    java.lang.Math.acos(x)
}

def acos(x: Array[Double]) = {
    scalaSci.DoubleArr.acos(x)
}


def acos(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.acos(x)
}

def acos(x: Matrix) = {
    scalaSci.Matrix.acos(x)
}


def acos(x: Vec) = {
    scalaSci.Vec.acos(x)
}


// atan

def atan(x: Double) = {
    java.lang.Math.atan(x)
}

def atan(x: Float) = {
    java.lang.Math.atan(x).asInstanceOf[Float]
}

def atan(x: Int) = {
    java.lang.Math.atan(x)
}

def atan(x: Short) = {
    java.lang.Math.atan(x)
}

def atan(x: Long) = {
    java.lang.Math.atan(x)
}

def atan(x: Array[Double]) = {
    scalaSci.DoubleArr.atan(x)
}


def atan(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.atan(x)
}

def atan(x: Matrix) = {
    scalaSci.Matrix.atan(x)
}


def atan(x: Vec) = {
    scalaSci.Vec.atan(x)
}




    // exp

def exp(x: Double) = {
    java.lang.Math.exp(x)
}

def exp(x: Float) = {
    java.lang.Math.exp(x).asInstanceOf[Float]
}

def exp(x: Int) = {
    java.lang.Math.exp(x)
}

def exp(x: Short) = {
    java.lang.Math.exp(x)
}

def exp(x: Long) = {
    java.lang.Math.exp(x)
}

def exp(x: Array[Double]) = {
    scalaSci.DoubleArr.exp(x)
}


def exp(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.exp(x)
}

def exp(x: Matrix) = {
    scalaSci.Matrix.exp(x)
}


def exp(x: Vec) = {
    scalaSci.Vec.exp(x)
}

// pow
def pow(x: Double, value: Double) = {
    java.lang.Math.pow(x, value)
}

def pow(x: Float, value: Float) = {
    java.lang.Math.pow(x, value).asInstanceOf[Float]
}

def pow(x: Int, value: Double) = {
    java.lang.Math.pow(x, value)
}

def pow(x: Short, value: Double) = {
    java.lang.Math.pow(x, value)
}

def pow(x: Long, value: Double) = {
    java.lang.Math.pow(x, value)
}

def pow(x: Array[Double], value: Double) = {
    scalaSci.DoubleArr.pow(x, value)
}


def pow(x: Matrix, value: Double) = {
    scalaSci.Matrix.pow(x, value)
}


def pow(x: Array[Array[Double]], value:Double) = {
    scalaSci.DoubleDoubleArr.pow(x, value)
}


def pow(x: Vec, value: Double) = {
    scalaSci.Vec.pow(x, value)
}
  
// log


def log(x: Double) = {
    java.lang.Math.log(x)
}

def log(x: Float) = {
    java.lang.Math.log(x).asInstanceOf[Float]
}

def log(x: Int) = {
    java.lang.Math.log(x)
}

def log(x: Short) = {
    java.lang.Math.log(x)
}

def log(x: Long) = {
    java.lang.Math.log(x)
}

def log(x: Array[Double]) = {
    scalaSci.DoubleArr.log(x)
}


def log(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.log(x)
}

def log(x: Matrix) = {
    scalaSci.Matrix.log(x)
}


def log(x: Vec) = {
    scalaSci.Vec.log(x)
}

    // log2


def log2(x: Double) = {
    var conv = java.lang.Math.log(2.0)
    java.lang.Math.log(x)/conv
}

def log2(x: Float) = {
    var conv = java.lang.Math.log(2.0f).asInstanceOf[Float]
    java.lang.Math.log(x).asInstanceOf[Float]/conv
}

def log2(x: Int) = {
    var conv = java.lang.Math.log(2.0)
    java.lang.Math.log(x)/conv
}

def log2(x: Short) = {
    var conv = java.lang.Math.log(2.0)
    java.lang.Math.log(x)/conv
}

def log2(x: Long) = {
    var conv = java.lang.Math.log(2.0)
    java.lang.Math.log(x)/conv
}

def log2(x: Array[Double]) = {
    scalaSci.DoubleArr.log2(x)
}

def log2(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.log2(x)
}

def log2(x: Matrix) = {
    scalaSci.Matrix.log2(x)
}


def log2(x: Vec) = {
    scalaSci.Vec.log2(x)
}

// log10

def log10(x: Double) = {
    java.lang.Math.log10(x)
}

def log10(x: Float) = {
    java.lang.Math.log10(x).asInstanceOf[Float]
}

def log10(x: Int) = {
    java.lang.Math.log10(x)
}

def log10(x: Short) = {
    java.lang.Math.log10(x)
}

def log10(x: Long) = {
    java.lang.Math.log10(x)
}

def log10(x: Array[Double]) = {
    scalaSci.DoubleArr.log10(x)
}


def log10(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.log10(x)
}

def log10(x: Matrix) = {
    scalaSci.Matrix.log10(x)
}


def log10(x: Vec) = {
    scalaSci.Vec.log10(x)
}


    // ceil

def ceil(x: Double) = {
    java.lang.Math.ceil(x)
}

def ceil(x: Float) = {
    java.lang.Math.ceil(x).asInstanceOf[Float]
}

def ceil(x: Int) = {
    java.lang.Math.ceil(x)
}

def ceil(x: Short) = {
    java.lang.Math.ceil(x)
}

def ceil(x: Long) = {
    java.lang.Math.ceil(x)
}

def ceil(x: Array[Double]) = {
    scalaSci.DoubleArr.ceil(x)
}


def ceil(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.ceil(x)
}

def ceil(x: Matrix) = {
    scalaSci.Matrix.ceil(x)
}


def ceil(x: Vec) = {
    scalaSci.Vec.ceil(x)
}

    // floor

def floor(x: Double) = {
    java.lang.Math.floor(x)
}

def floor(x: Float) = {
    java.lang.Math.floor(x).asInstanceOf[Float]
}

def floor(x: Int) = {
    java.lang.Math.floor(x)
}

def floor(x: Short) = {
    java.lang.Math.floor(x)
}

def floor(x: Long) = {
    java.lang.Math.floor(x)
}

def floor(x: Array[Double]) = {
    scalaSci.DoubleArr.floor(x)
}


def floor(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.floor(x)
}

def floor(x: Matrix) = {
    scalaSci.Matrix.floor(x)
}


def floor(x: Vec) = {
    scalaSci.Vec.floor(x)
}

// round

def round(x: Double) = {
    java.lang.Math.round(x)
}

def round(x: Float) = {
    java.lang.Math.round(x).asInstanceOf[Float]
}

def round(x: Int) = {
    java.lang.Math.round(x)
}

def round(x: Short) = {
    java.lang.Math.round(x)
}

def round(x: Long) = {
    java.lang.Math.round(x)
}

def round(x: Array[Double]) = {
    scalaSci.DoubleArr.round(x)
}


def round(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.round(x)
}

def round(x: Matrix) = {
    scalaSci.Matrix.round(x)
}


def round(x: Vec) = {
    scalaSci.Vec.round(x)
}


// sqrt

def sqrt(x: Double) = {
    java.lang.Math.sqrt(x)
}

def sqrt(x: Float) = {
    java.lang.Math.sqrt(x).asInstanceOf[Float]
}

def sqrt(x: Int) = {
    java.lang.Math.sqrt(x)
}

def sqrt(x: Short) = {
    java.lang.Math.sqrt(x)
}

def sqrt(x: Long) = {
    java.lang.Math.sqrt(x)
}

def sqrt(x: Array[Double]) = {
    scalaSci.DoubleArr.sqrt(x)
}


def sqrt(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.sqrt(x)
}

def sqrt(x: Matrix) = {
    scalaSci.Matrix.sqrt(x)
}


def sqrt(x: Vec) = {
    scalaSci.Vec.sqrt(x)
}


    // toDegrees

def toDegrees(x: Double) = {
    java.lang.Math.toDegrees(x)
}

def toDegrees(x: Float) = {
    java.lang.Math.toDegrees(x).asInstanceOf[Float]
}

def toDegrees(x: Int) = {
    java.lang.Math.toDegrees(x)
}

def toDegrees(x: Short) = {
    java.lang.Math.toDegrees(x)
}

def toDegrees(x: Long) = {
    java.lang.Math.toDegrees(x)
}

def toDegrees(x: Array[Double]) = {
    scalaSci.DoubleArr.toDegrees(x)
}


def toDegrees(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.toDegrees(x)
}

def toDegrees(x: Matrix) = {
    scalaSci.Matrix.toDegrees(x)
}


def toDegrees(x: Vec) = {
    scalaSci.Vec.toDegrees(x)
}

 // toRadians

def toRadians(x: Double) = {
    java.lang.Math.toRadians(x)
}

def toRadians(x: Float) = {
    java.lang.Math.toRadians(x).asInstanceOf[Float]
}

def toRadians(x: Int) = {
    java.lang.Math.toRadians(x)
}

def toRadians(x: Short) = {
    java.lang.Math.toRadians(x)
}

def toRadians(x: Long) = {
    java.lang.Math.toRadians(x)
}

def toRadians(x: Array[Double]) = {
    scalaSci.DoubleArr.toRadians(x)
}


def toRadians(x: Array[Array[Double]]) = {
    scalaSci.DoubleDoubleArr.toRadians(x)
}

def toRadians(x: Matrix) = {
    scalaSci.Matrix.toRadians(x)
}


def toRadians(x: Vec) = {
    scalaSci.Vec.toRadians(x)
}


    
 def  diag(n:Int): Matrix = {
       scalaSci.Matrix.diag(n)
 }

/* example:
var ll = List(9, -8.8, 6.5)
var  mm = diag(ll)
*/
def diag(vals: Seq[Double]) = 
  scalaSci.EJML.Mat.diag(vals)


def extractDiag(x: Mat) = x.extractDiag    // ?? test
/* example:
var mMat = rand0(3, 6); var vMat = rand0(1,10)
var isNotVec = isVector(mMat)
var isVec = isVector(vMat)
*/
def isVector(x: Mat) =    x.isVector

 /* example:
var tstMat = testMat(10, 12)
*/
def testMat(N: Int, M: Int) = 
  scalaSci.EJML.Mat.testMat(N, M)

def eye(n: Int): Matrix = {
  scalaSci.Matrix.eye(n)
}



def Eye(n: Int): Array[Array[Double]] = {
  scalaSci.DoubleDoubleArr.eye(n)
}


def eye(n: Int, m: Int): Matrix = {
  scalaSci.Matrix.eye(n, m)
}

def Eye(n: Int, m: Int): Array[Array[Double]] = {
  scalaSci.DoubleDoubleArr.eye(n, m)
}


def ones(n: Int, m:Int): Matrix = {
     scalaSci.Matrix.ones(n, m)
}

def ones(n: Int): Matrix = {
 scalaSci.Matrix.ones(n, n)
}



def rand(n: Int, m:Int): Matrix = {
     scalaSci.Matrix.rand(n, m)
}

def rand(n: Int): Matrix = {
 scalaSci.Matrix.rand(n, n)
}



 def zeros(n: Int, m:Int): Matrix = {
      scalaSci.Matrix.zeros(n,m)
  }

def zeros(n: Int): Matrix = {
 scalaSci.Matrix.zeros(n, n)
}


def zeros0(n: Int): Matrix = {
 scalaSci.Matrix.zeros(n, n)
}


  def fill(n: Int, m:Int, vl: Double): Matrix = {
    scalaSci.Matrix.fill(n, m, vl)
  }

def fill(n: Int, vl:Double): Matrix = {
 scalaSci.Matrix.fill(n, n, vl)
}


    def Fill(n: Int, m:Int, vl: Double): Array[Array[Double]] = {
        scalaSci.DoubleDoubleArr.Fill(n, m, vl)
    }

    def  Ones(n:Int, m:Int): Array[Array[Double]] = {
        scalaSci.DoubleDoubleArr.ones(n, m)
    }

    def  Zeros(n:Int, m:Int): Array[Array[Double]] = {
        scalaSci.DoubleDoubleArr.zeros(n, m)
    }

 
/* ?example:
var f58 = fill0(5, 8)
var f55 = fill0(5)
*/
   
 def rand0(n: Int, m:Int) = {
       scalaSci.EJML.Mat.random(n,m)
    }

def rand0(n: Int) = {
       scalaSci.EJML.Mat.random(n,n)
    }

def ones0(n: Int, m: Int) = {
   scalaSci.EJML.Mat.ones(n,m)
  }

def ones0(n: Int) = {
   scalaSci.EJML.Mat.ones(n,n)
  }

def zeros0(n: Int, m: Int) = {
   scalaSci.EJML.Mat.zeros(n,m)
  }



def fill0(n: Int, m: Int, value: Double) = {
   scalaSci.EJML.Mat.fill(n, m, value)
  }

def fill0(n: Int, value: Double) = {
   scalaSci.EJML.Mat.fill(n, n, value)
  }


def randt(n: Int, m:Int): Matrix = {
       scalaSci.Matrix.randt(n,m)
    }

def Rand(n: Int, m:Int): Array[Array[Double]] = {
        scalaSci.DoubleDoubleArr.rand(n, m)
    }

def Rand(n: Int): Array[Array[Double]] = {
        scalaSci.DoubleDoubleArr.rand(n, n)
    }

def vrand(n:Int):scalaSci.Vec = {
        scalaSci.Vec.rand(n)
    }

def sin(m: Mat) = {
   scalaSci.EJML.Mat.sin(m)
  }

def cos(m: Mat) = {
   scalaSci.EJML.Mat.cos(m)
  }

def tan(m: Mat) = {
   scalaSci.EJML.Mat.tan(m)
  }

def asin(m: Mat) = {
   scalaSci.EJML.Mat.asin(m)
  }

def acos(m: Mat) = {
   scalaSci.EJML.Mat.acos(m)
  }

def atan(m: Mat) = {
   scalaSci.EJML.Mat.atan(m)
  }


def sinh(m: Mat) = {
   scalaSci.EJML.Mat.sinh(m)
  }

def cosh(m: Mat) = {
   scalaSci.EJML.Mat.cosh(m)
  }

def tanh(m: Mat) = {
   scalaSci.EJML.Mat.tanh(m)
  }


def  Ones(n:Int): Array[Double] = {
        scalaSci.DoubleArr.Ones(n)
    }


    def vones(n: Int): Vec = {
        scalaSci.Vec.vones(n)
    }

    def  Zeros(n: Int): Array[Double] = {
        scalaSci.DoubleArr.Zeros(n)
  }

 def  vzeros(n: Int): Vec = {
     scalaSci.Vec.vzeros(n)
    }

 def vfill(n: Int, value: Double): Vec = {
      scalaSci.Vec.vfill(n, value)
  }

def vfill(n: Int, value: Int): Vec = {
      scalaSci.Vec.vfill(n, value)
  }

def  vFill(n:Int, value: Double): Array[Double] = {
      scalaSci.DoubleArr.Fill(n, value)
      }


 def inc(begin: Double, pitch: Double,  end: Double): Vec = {
     scalaSci.Vec.inc(begin, pitch, end)
    }

 def  Inc(begin: Double, pitch: Double,  end: Double): Array[Double] = {
    scalaSci.DoubleArr.Inc(begin, pitch, end)
    }

def linspace(startv: Double, endv: Double) = scalaSci.Vec.linspace(startv, endv)

def linspace(startv: Double, endv: Double, nP: Int) = scalaSci.Vec.linspace(startv, endv, nP)

def logspace(startv: Double, endv: Double, nP: Int, logBase: Double) = scalaSci.Vec.logspace(startv, endv, nP, logBase)

def logspace(startv: Double, endv: Double, nP: Int) = scalaSci.Vec.logspace(startv, endv, nP, 10.0)  // Matlab-like defaults

def logspace(startv: Double, endv: Double) = scalaSci.Vec.logspace(startv, endv, 50, 10.0)  // Matlab-like defaults

// implicit conversion from Double[Array] to Vec
   def toVector(da: Array[Double]): scalaSci.Vec = {
       scalaSci.Vec.toVector(da)
   }

// dot
def dot(a: scalaSci.Vec, b: scalaSci.Vec): scalaSci.Vec = {
   a.dot(b)
   }  

def dot(a: scalaSci.Matrix, b: scalaSci.Matrix): scalaSci.Matrix = {
  a.dot(b)
   }  

  
def dot(a: scalaSci.EJML.Mat, b: scalaSci.EJML.Mat): Double = {
  a.dot(b)
   }  
  
  
    // Signal Processing Routines
 def  fft(sig: Array[Double]) = {
       scalaSci.math.array.BasicDSP.fft(sig)
   }

 def fft(sig: Vec) = {
     scalaSci.math.array.BasicDSP.fft(sig)
 }


def mean(v: Vec): Double = {
    mean(v.getv)
}

def sum(v: Vec):Double = {
    sum(v.getv)
}    

def size(v: Vec): Int = {   v.length }

def length(v: Vec): Int = { v.length }

def size(a: scalaSci.Matrix): Array[Int] =  {
  var siz = new Array[Int](2)
  siz(0) = a.Nrows;  siz(1) = a.Ncols
 siz
}


def  length(a: scalaSci.Matrix): Int = { a.length }

   
// aggregation routines
// COLUMNWISE 
def sum( v: Matrix): Array[Double] = {
   scalaSci.Matrix.sum(v)
}


def sum( v: Array[Double]): Double = {
   scalaSci.DoubleArr.sum(v)
}

def  sum(v: Array[Array[Double]]): Array[Double] = {
    scalaSci.DoubleDoubleArr.sum(v)
}


def mean( v: Matrix): Array[Double] = {
   scalaSci.Matrix.mean(v)
}


def mean( v: Array[Double]): Double = {
   scalaSci.DoubleArr.mean(v)
}

def  mean(v: Array[Array[Double]]): Array[Double] = {
    scalaSci.DoubleDoubleArr.mean(v)
}

def prod( v: Matrix): Array[Double] = {
   scalaSci.Matrix.prod(v)
}


def prod( v: Array[Double]): Double = {
   scalaSci.DoubleArr.prod(v)
}

def  prod(v: Array[Array[Double]]): Array[Double] = {
    scalaSci.DoubleDoubleArr.prod(v)
}


def min(darr: Array[Double]): Double = {
   scalaSci.DoubleArr.min(darr)
}


def max(darr: Array[Double]): Double = {
   scalaSci.DoubleArr.max(darr)
}


def min(darr: Array[Array[Double]]): Array[Double] = {
   scalaSci.DoubleDoubleArr.min(darr)
}

def max(darr: Array[Array[Double]]): Array[Double] = {
   scalaSci.DoubleDoubleArr.max(darr)
}

def min( v: Matrix): Array[Double] = {
   scalaSci.Matrix.min(v)
}


def min(v: Vec): Double = {
  scalaSci.Vec.min(v)
}

def max( v: Matrix): Array[Double] = {
   scalaSci.Matrix.max(v)
}


def max(v: Vec): Double = {
  scalaSci.Vec.max(v)
}

// ROWWISE 
def sumR( v: Matrix): Array[Double] = {
   scalaSci.Matrix.sumR(v)
}



def meanR( v: Matrix): Array[Double] = {
   scalaSci.Matrix.meanR(v)
}


def prodR( v: Matrix): Array[Double] = {
   scalaSci.Matrix.prodR(v)
}



def minR( v: Matrix): Array[Double] = {
   scalaSci.Matrix.minR(v)
}


def maxR( v: Matrix): Array[Double] = {
   scalaSci.Matrix.maxR(v)
}


// transpose operations
def T(m: Matrix): Matrix = {
  scalaSci.Matrix.T(m)
}

// transpose operations
def trans(m: Matrix): Matrix = {
  scalaSci.Matrix.transpose(m)
}


def transpose(m: Matrix): Matrix = {
  scalaSci.Matrix.transpose(m)
}

def T(m: Mat): Mat = {
   scalaSci.EJML.Mat.transpose(m)
}

def trans(m: Mat): Mat = {
   scalaSci.EJML.Mat.transpose(m)
}

def transpose(m: Mat): Mat = {
   scalaSci.EJML.Mat.transpose(m)
}


def reshape(v: Array[Array[Double]], n: Int, m: Int): Array[Array[Double]] = {
  scalaSci.DoubleDoubleArr.reshape(v, n, m)
}

// ?? test:   var x = rand0(5, 6); var xr = x.reshape(3, 10)
def reshape(x: Mat, n: Int, m: Int) = 
  x.reshape(n, m)

def resample(v: Matrix, n: Int, m: Int): Matrix = {
  scalaSci.Matrix.resample(v, n, m)
}

def  corr(v1: Array[Double], v2: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.correlation(v1, v2);
     r
 }


def correlation(v1: Array[Double], v2: Array[Double]): Double = {
  var r = corr(v1, v2)
  r
}

def  corr(v1: Array[Array[Double]], v2: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = scalaSci.math.array.StatisticSample.correlation(v1, v2);
     r
 }

def  Var(v: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.variance(v);
     r
 }

def variance(v: Array[Double]): Double = {
  var r = Var(v)
  r
}

def variance(m: Matrix): Array[Double] = {
    scalaSci.Matrix.variance(m)
}

def Var(m: Matrix): Array[Double] = {
    scalaSci.Matrix.variance(m)
}

def  std(v: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.stddeviation(v);
     r
 }

def stddeviation(v: Array[Double]): Double = {
  var r = std(v)
  r
}

def  cov(v1: Array[Double], v2: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.covariance(v1, v2);
     r
 }


def covariance(v1: Array[Double], v2: Array[Double]): Double = {
  var r = cov(v1, v2)
  r
}

def  cov(v1: Array[Array[Double]], v2: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = scalaSci.math.array.StatisticSample.covariance(v1, v2);
     r
 }

def  covariance(v1: Array[Array[Double]], v2: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = cov(v1, v2)
     r
 }

def  cov(v: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = scalaSci.math.array.StatisticSample.covariance(v, v);
     r
 }

 def  covariance(v: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = scalaSci.math.array.StatisticSample.covariance(v, v);
     r
 }

    
def correlation(v1: Array[Array[Double]], v2: Array[Array[Double]]): Array[Array[Double]] = {
  var r = corr(v1, v2)
  r
}




def covariance(v1: Matrix, v2: Matrix): Matrix = {
  scalaSci.Matrix.covariance(v1, v2)
}


def cov(v1: Matrix, v2: Matrix): Matrix = {
  scalaSci.Matrix.covariance(v1, v2)
}





def  corr(v: Array[Array[Double]]): Array[Array[Double]] =   {
     var r = scalaSci.math.array.StatisticSample.correlation(v, v);
     r
 }


def  correlation(v: Array[Array[Double]]): Array[Array[Double]] =   {
     var r =  corr(v,v);
     r
 }




def  det(M: Matrix) = {
  scalaSci.Matrix.det(M)
}

def det(A: Array[Array[Double]]) = {
  scalaSci.DoubleDoubleArr.det(A)
}

def det(A: Mat) = {
   scalaSci.EJML.Mat.det(A)
}


def trace(M: Matrix): Double = {
   LinearAlgebra.trace( M.getv)
}

def trace(DD: Array[Array[Double]]) = {
LinearAlgebra.trace(DD)
}

def trace(M: Mat): Double = {
 M.trace
}



//////////////////


// JSCI based routines
//  Compute the L2 norm 
def  norm(vin: Vec): Double = {
   JSci.maths.wavelet.Signal.norm(vin.getv)
 }

def  cfft(vin: Vec): Array[JSci.maths.Complex] = {
   var vlen = length(vin)
   println(" in FFT, vlen = "+vlen)
   var pow2i = floor(log2(vlen))
   var newSize = pow(2, pow2i).asInstanceOf[Int]
   var pow2Sig = vin(0, newSize-1)
   JSci.maths.wavelet.Signal.fft(pow2Sig.getv)
}

def absFFT(vin: Vec): Array[Double] = {
   var vlen = length(vin)
   var pow2i = floor(log2(vlen))
   var newSize = pow(2, pow2i).asInstanceOf[Int]
   var pow2Sig = vin(0, newSize-1)
   JSci.maths.wavelet.Signal.absFFT(pow2Sig.getv)
}

def cfftInverse(vcompl:  Array[JSci.maths.Complex]): Array[JSci.maths.Complex] = {
   JSci.maths.wavelet.Signal.fftInverse(vcompl)
}

    // gets the real parts from a Complex array
def getRealValues(carr: Array[JSci.maths.Complex]): Array[Double] = {
    var len = carr.length
    var doubleArr = new Array[Double](len)
    for (k<-0 to len-1)
      doubleArr(k) = carr(k).real()
    doubleArr
}
/*
 def inc2d(beginX: Double, pitchX: Double,  endX: Double, beginY: Double, pitchY: Double,  endY: Double): Vec = {
     var siz = ((end - begin) / pitch).asInstanceOf[Int]
     var doubleArr = new Array[Double](siz)
     var i=0;  while (i < siz) {   doubleArr(i) = begin + i * pitch;  i += 1;  }
   new Vec(doubleArr)
	}
*/


    // some linear algebra operations using the NUMAL library

def inv(m: Matrix): Matrix = {
     var mcopy = new Matrix(m)
     scalaSci.Matrix.decinv(mcopy)
  }


def inv(a: Array[Array[Double]]) = {
  scalaSci.DoubleDoubleArr.inv(a)
}

def eig(da: Array[Array[Double]]) = {
  scalaSci.DoubleDoubleArr.eig(da)
}


def eig(ar:  Matrix, ai: Matrix)= {
   scalaSci.Matrix.eig(ar, ai)
}


def eig(ar:  Matrix)= {
   scalaSci.Matrix.eig(ar)
}

def   eig(am: Mat) =  {
   var eigd = scalaSci.EJML.Mat.eig(am)    // get the EigenDecomposition
   var N = eigd.getNumberOfEigenvalues
    // allocate space for eigenvalues and eigenvectors
   var eigvals  =  new Array[Double](N)
   var eigvecs = new Array[Array[Double]](N, N)
   for (k<-0 to N-1) {
     eigvals(k) = eigd.getEigenvalue(k).getReal
     var  cevec = eigd.getEigenVector(k)
     for (l<-0 to N-1)
        eigvecs(k)(l) = cevec.get(l, 0)
  }
   ( eigvecs, eigvals, eigd)
}
   
// get the eigenvalues and eigenvectors of m
def   eig(am: Mat, denseVector: Boolean) =  {
   var eigd = scalaSci.EJML.Mat.eig(am)    // get the EigenDecomposition
   var N = eigd.getNumberOfEigenvalues
    // allocate space for eigenvalues and eigenvectors
   var eigvals  =  new Array[Complex64F](N)
   var eigvecs = new Array[DenseMatrix64F](N)
   for (k<-0 to N-1) {
     eigvals(k) = eigd.getEigenvalue(k)
     eigvecs(k) = eigd.getEigenVector(k).getMatrix
  }

   (eigvecs, eigvals)
}

// get the eigenvalues of m
def eigD(am: Mat) = {   
   var eigd = scalaSci.EJML.Mat.eig(am)    // get the EigenDecomposition
   var N = eigd.getNumberOfEigenvalues
 // allocate space for eigenvalues and eigenvectors
   var eigvals  =  new Array[Complex64F](N)
   for (k<-0 to N-1) 
     eigvals(k) = eigd.getEigenvalue(k)
     
 eigvals
}


// get the eigenvectors of m
def   eigV(am: Mat) =  {
   var eigd = scalaSci.EJML.Mat.eig(am)    // get the EigenDecomposition
   var N = eigd.getNumberOfEigenvalues
    // allocate space for eigenvalues and eigenvectors
   var eigvecs = new Array[DenseMatrix64F](N)
   for (k<-0 to N-1) 
     eigvecs(k) = eigd.getEigenVector(k).getMatrix
  eigvecs
}

// return the Kronecker product of two matrices
def kron(Mr: Mat, M: Mat) = {
  Mr.kron(M)
}

//def  rank(M: Mat): Int = {
//  M.rank
//}

//def trace(M: Mat): Double = {
//   M.trace
//}

/*
def Eigen_V(M: Mat): Mat = {
   new Mat(LinearAlgebra.eigen(M.v).getV().getArray())
}

def V(M: Mat): Mat = {
   Eigen_V( M)
 }

def  Eigen_D(M: Mat) = {
   new Mat(LinearAlgebra.eigen(M.v).getD().getArray())
}

def  D(M: Mat):Mat = {
   Eigen_D( M)
}
*/
// svd Singular value decomposition.
//    (U,S,V) = svd(X) produces a diagonal matrix S, of the same 
//    dimension as X and with nonnegative diagonal elements in
//    decreasing order, and unitary matrices U and V so that X = U*S*V'.
 
def svd(am: Mat) = {
   var svddd = scalaSci.EJML.Mat.svd(am)    // get the SVD Decomposition
   var U = svddd.getU
   var S = svddd.getW
   var V = svddd.getV

 (U, S, V)
}


def svdRank(a: Matrix) = {
  scalaSci.Matrix.svdRank(a)
}

def svd(a: Matrix) = {
  scalaSci.Matrix.svd(a)
}

def gsssol( a: Matrix, b: Array[Double]): Matrix = {
    scalaSci.Matrix.gsssol(a, b)
   }

    // determines the generalized inverse A^+ of the mXn matrix A (m >=n). The singular value decomposition A = U Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β²Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�β€™Ξ’Β¬Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�οΏ½Ξ²β‚¬Β Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β²Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�β€™Ξ’Β¬Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�οΏ½Ξ²β‚¬Β Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β²Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β²Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β²Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β²Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β²Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�β€™Ξ’Β¬Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β¬Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β²Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�β€™Ξ’Β¬Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β€�Β¬ΞΏΞ�Β½Ξ�οΏ½Ξ²β‚¬Β Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β¬Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ�οΏ½Ξ�οΏ½ΞΏΞ�Β½Ξ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½Ξ�οΏ½ΞΏΞ�Β½Ξ�Ξ�Ξ�οΏ½Ξ’Β½Ξ�οΏ½Ξ’Β²Ξ�Β²Ξ²β‚¬οΏ½Ξ’Β¬Ξ�Β²Ξ²β‚¬οΏ½Ξ�β€ Ξ�οΏ½ΞΏΞ�Β½Ξ�Β²Ξ²β€�Β¬Ξ²β€�Ξ†Ξ�οΏ½Ξ²β‚¬β„ΆΞ�β€™Ξ’Β½ V^T is  first carried out
def psdInv( a: Matrix):Matrix = {
    var em = new Array[Double](8)
      // pass default values to simplify the interface
    em(0) = 1.0e-14  // the machine precision
    em(2) = 1.0e-12  // the relative precision of singular values
    em(4) = 80.0  // the maximal number of iterations to be performed
    em(6) = 1.0e-10  // the minimal nonneglected singular value
    
    var N = a.Nrows; var M = a.Ncols
        var transPsdInv = new Matrix(a)   // on exit:  the tanspose of the pseudo-inverse
        numal.Linear_algebra.psdinv(transPsdInv.getv, N-1, M-1, em)
        transPsdInv
}



def subm(a: Matrix, rs: Int, incr: Int, re: Int, cs: Int, incc: Int, ce: Int) = {
   a.subm(rs, incr, re, cs, incc, ce)
  }

def submr(a: Matrix, rs: Int, incr: Int, re: Int) = {
   a.submr(rs, incr, re)
  }

def submc(a: Matrix, cs: Int, incc: Int, ce: Int) = {
   a.submc(cs, incc, ce)
  }

def inv(a: scalaSci.EJML.Mat) = scalaSci.EJML.Mat.inv(a)

//   Solves for X in the following equation:
//      x = a^{-1}  b
//   where 'a' is this matrix and 'b' is an n by p matrix.
//   If the system could not be solved then SingularMatrixException is thrown.  Even
//   if no exception is thrown 'a' could still be singular or nearly singular.
//      @param b n by p matrix. Not modified.
//      @return The solution for 'x' that is n by p.
def solve(A: scalaSci.EJML.Mat, b: scalaSci.EJML.Mat) = 
   A.solve(b)



//  Computes the Frobenius normal of the matrix, sqrt(sum(diag(X'*X))).
  /* ?? test
//   The condition p = 2 number of a matrix is used to measure the sensitivity of the linear
//     system <b>Ax=b</b>.  A value near one indicates that it is a well conditioned matrix.
 
var a = rand0(4)
var nf = normF(a)
*/   
def  normF(a: scalaSci.EJML.Mat) =    a.normF
     
//  ?? test
def conditionP2( a: scalaSci.EJML.Mat) =    a.conditionP2
     
}



